package com.wondertek.poms.service.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.wondertek.poms.common.constant.Constants;
import com.wondertek.poms.common.constant.CurrentUser;
import com.wondertek.poms.common.exception.MessageCodes;
import com.wondertek.poms.common.log.MethodLog;
import com.wondertek.poms.common.utils.excel.ImportExcel;
import com.wondertek.poms.common.utils.validate.ValidateFilter;
import com.wondertek.poms.common.vo.PageBean;
import com.wondertek.poms.common.vo.ResultBean;
import com.wondertek.poms.core.service.IEquityTreeService;
import com.wondertek.poms.core.service.IEquityNodeService;
import com.wondertek.poms.core.service.IProductGroupService;
import com.wondertek.poms.dao.po.EquityNode;
import com.wondertek.poms.dao.po.EquityTree;
import com.wondertek.poms.dao.po.ProductGroup;
import com.wondertek.poms.dao.pojo.EquityNodePojo;
import com.wondertek.poms.dao.pojo.EquityTreeAndNodesExcelPojo;
import com.wondertek.poms.service.message.SendAbility;
import com.wondertek.poms.service.vo.EquityNodeVo;
import com.wondertek.poms.service.vo.EquityTreeVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

@Api(value = "EquityTreeController", description = "权益树管理")
@RequestMapping(value="/equity-tree")
@RestController
@Slf4j
public class EquityTreeController {

    @Autowired
    private IEquityTreeService equityTreeService;
    @Autowired
    private IEquityNodeService equityNodeService;
    @Autowired
    private IProductGroupService productGroupService;
    @Autowired
    private SendAbility sendAbility;

    @ApiOperation("权益树管理 列表")
    @GetMapping(value = "/list")
    @ResponseBody
    public ResultBean list(@RequestParam(defaultValue = "1") int page,
                           @RequestParam(defaultValue = "20") int rows,
                           @RequestParam(defaultValue = "CREATE_TIME") String sidx,
                           @RequestParam(defaultValue = "desc") String sord){
        Page<EquityTree> list=equityTreeService.findAll(page,rows,sord,sidx);
        return PageBean.ok(list.getTotalPages(),list.getTotalElements(),list.getContent());
    }

    @ApiOperation("权益树管理 添加")
    @PostMapping(value = "/add")
    @ResponseBody
    @MethodLog(module = "权益树新增",insertDB=true,opterate = 1)
    public ResultBean add(@RequestBody EquityTreeVo equityTreeVo){
        List<String> messageList = ValidateFilter.getFilterMessage(equityTreeVo, Constants.VALIDATE_DEFAULT);
        if (!messageList.isEmpty()) {
            return ResultBean.error(messageList.toString());
        }
        if(isRepeat(equityTreeVo)){
            return ResultBean.error(MessageCodes.get(MessageCodes.M980014));
        }

        EquityTree equityTree=new EquityTree();
        BeanUtils.copyProperties(equityTreeVo,equityTree);
        equityTree.setEquityTreeDepth(0);
        equityTree.setCreateTime(new Date());
        equityTree.setAuthor(CurrentUser.currUserName());
        if("0".equals(equityTreeVo.getAutoPublish())){
            equityTree.setActiveStatus("2");
        }else if("1".equals(equityTreeVo.getAutoPublish())){
            //todo  权益树发布
            //equityTree.setActiveStatus("0");
            Boolean flag = sendAbility.sendToAbility(equityTree.getId(),1,equityTree.getEquityTreeName(),"1");
            if(flag){
                equityTree.setActiveStatus("0");
            }else {
                equityTree.setActiveStatus("2");
            }
        }

        equityTree=equityTreeService.save(equityTree);
        createRootNode(equityTree);
        equityTree.setEquityTreeDepth(1);
        equityTreeService.merge(equityTree);
        return ResultBean.ok();
    }

    @ApiOperation("权益树管理 删除")
    @DeleteMapping(value = "/delete")
    @ResponseBody
    @MethodLog(module = "权益树删除",insertDB=true,opterate = 3)
    public ResultBean delete(String ids){
        if (StrUtil.isBlank(ids)) {
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        StringBuffer msg = new StringBuffer();
        StringBuffer errMessage = new StringBuffer();
        AtomicInteger errorNum = new AtomicInteger();//错误数
        AtomicInteger successNum = new AtomicInteger();//成功数
        String[] idArray = ids.split(",|，");
        for(String id:idArray){
            if(checkDate(id,errMessage,errorNum)){
                equityTreeService.deleteEquityTree(Convert.toLong(id));
                successNum.addAndGet(1);
            }
        }
        msg.append("删除成功"+successNum.get()+"条. ");
        if (errorNum.get() > 0) {
            msg.append("删除失败"+errorNum.get()+"条，失败原因：").append(errMessage);
            return ResultBean.error(msg.toString());
        }
        return ResultBean.ok(msg.toString());
    }

    public Boolean checkDate(String id,StringBuffer errMessage,AtomicInteger errNum){
        Boolean flag=true;
        EquityTree equityTree=equityTreeService.get(Convert.toLong(id));
        if("0".equals(equityTree.getActiveStatus())){
            errNum.addAndGet(1);
            flag = false;
            errMessage.append("删除出错：id为 "+id+"的权益树已发布.  ");
        }
        if(equityNodeService.checkEquityNodeExist(Convert.toLong(id))){
            errNum.addAndGet(1);
            flag = false;
            errMessage.append("删除出错：id为 "+id+"的权益树中的权益节点已被配置.  ");
        }
        return flag;

    }

    @ApiOperation("通过权益树id获取全部节点")
    @GetMapping(value = "/get-node-lists-by-treeId")
    @ResponseBody
    public ResultBean getEquityNodeListByTreeId (String id){
        if (StrUtil.isBlank(id)) {
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        EquityNodePojo equityNodePojo=equityTreeService.getAllEquityNodesByTreeId(Convert.toLong(id),false);
        return ResultBean.ok(equityNodePojo);
    }


    @PostMapping(value = "/import")
    @ResponseBody
    @MethodLog(module = "权益树导入",insertDB=true,opterate = 6)
    public ResultBean importEquityTree(MultipartFile file) throws Exception{
        StringBuffer msg = new StringBuffer();
        StringBuffer errMessage = new StringBuffer();
        AtomicInteger successNum = new AtomicInteger();//成功导入权益树
        AtomicInteger errorNum = new AtomicInteger();//错误数
        try {
            ImportExcel ei = new ImportExcel(file, 1, 0);
            List<EquityTreeAndNodesExcelPojo> list = ei.getDataList(EquityTreeAndNodesExcelPojo.class);
            if (list.isEmpty()) {
                return ResultBean.error("传入excel为空");
            }
            Map<String, EquityTreeVo> map = new HashMap<>();
            //msg.append(list.size());
            //权益树对象的封装
            map=getPcEquityTreeMap(map, list);
            Boolean flag=checkImport(map,list,errMessage);
            if(!flag){
                return ResultBean.error(errMessage.toString());
            }
            //权益树的规则验证以及保存
            saveEquityTree(msg, errMessage, successNum, errorNum, map, list);

        } catch (InvalidFormatException | InstantiationException | IllegalAccessException | IOException e) {
            e.printStackTrace();
        }
        if (errorNum.intValue() > 0) {
            return ResultBean.error(msg.toString());
        }
        return ResultBean.ok();
    }

    //todo  产品组发布
    @GetMapping(value = "/online")
    @ResponseBody
    @MethodLog(module = "权益树发布",insertDB=true,opterate = 4)
    public ResultBean online(String ids){
        if(StrUtil.isBlank(ids)){
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        StringBuffer msg = new StringBuffer();
        StringBuffer errMessage = new StringBuffer();
        AtomicInteger errorNum = new AtomicInteger();//错误数
        AtomicInteger successNum = new AtomicInteger();//成功数
        String[] idArray = ids.split(",|，");
        for(String id:idArray){
            EquityTree equityTree=equityTreeService.get(Convert.toLong(id));
            publishTree(equityTree,1,errMessage,errorNum,successNum);
        }
        msg.append("发布成功"+successNum.get()+"条. ");
        if (errorNum.get() > 0) {
            msg.append("发布失败"+errorNum.get()+"条：").append(errMessage);
            return ResultBean.error(msg.toString());
        }
        return ResultBean.ok(msg);
    }


    @GetMapping(value = "/offline")
    @ResponseBody
    @MethodLog(module = "权益树撤回",insertDB=true,opterate = 5)
    public ResultBean offline(String ids){
        if(StrUtil.isBlank(ids)){
            return ResultBean.error(MessageCodes.get(MessageCodes.M980203));
        }
        StringBuffer msg = new StringBuffer();
        StringBuffer errMessage = new StringBuffer();
        AtomicInteger errorNum = new AtomicInteger();//错误数
        AtomicInteger successNum = new AtomicInteger();//成功数
        String[] idArray = ids.split(",|，");
        for(String id:idArray){
            EquityTree equityTree=equityTreeService.get(Convert.toLong(id));
            if("1".equals(equityTree.getActiveStatus())){
                errorNum.addAndGet(1);
                errMessage.append("撤回出错：id为 "+id+"的权益树已撤回.  ");
            }else if (equityNodeService.checkEquityNodeExist(Convert.toLong(id))){
                errorNum.addAndGet(1);
                errMessage.append("撤回出错：id为 "+id+"的权益树已有节点被配置.  ");
            }else{
               publishTree(equityTree,2,errMessage,errorNum,successNum);
            }
        }
        msg.append("撤回成功"+successNum.get()+"条. ");
        if (errorNum.get() > 0) {
            msg.append("撤回失败"+errorNum.get()+"条：").append(errMessage);
            return ResultBean.error(msg.toString());
        }
        return ResultBean.ok(msg);
    }


    //todo
    public void publishTree(EquityTree equityTree,int oprCode,StringBuffer errMessage,AtomicInteger errorNum,AtomicInteger successNum){
        log.info("开始发送能力平台流程|权益树id："+equityTree.getId());
         Boolean flag = sendAbility.sendToAbility(equityTree.getId(),oprCode,equityTree.getEquityTreeName(),"1");
         log.info("发送能力平台流程结束|权益树id："+equityTree.getId()+",结果："+flag);
         if(flag){
            successNum.addAndGet(1);
            if(oprCode==1){
                equityTree.setActiveStatus("0");
            }else {
                equityTree.setActiveStatus("1");
            }
            EquityTree.putTimeAndUser(equityTree);
            equityTreeService.save(equityTree);
        }else {
            errorNum.addAndGet(1);
            errMessage.append("权益树： ").append(equityTree.getId()).append("失败！");
        }
    }

    @GetMapping(value = "/get-all")
    @ResponseBody
    public ResultBean getAll(){
        EquityTree equityTree=new EquityTree();
        equityTree.setActiveStatus("0");
        List<EquityTree> list=equityTreeService.findAll(equityTree);
        for(EquityTree temp:list){
            List<EquityNodePojo> nodes=new ArrayList<>();
            EquityNodePojo equityNodePojo=equityTreeService.getAllEquityNodesByTreeId(temp.getId(),false);
            nodes.add(equityNodePojo);
            temp.setNodes(nodes);
        }
        return ResultBean.ok(list);
    }


    @GetMapping(value = "/get-valid-tree")
    @ResponseBody
    public ResultBean getValidTree(){
        EquityTree equityTree=new EquityTree();
        equityTree.setActiveStatus("0");
        List<EquityTree> list=equityTreeService.findAll(equityTree);
        for(EquityTree temp:list){
            List<EquityNodePojo> nodes=new ArrayList<>();
            EquityNodePojo equityNodePojo=equityTreeService.getAllEquityNodesByTreeId(temp.getId(),true);
            //兼容前端不给空数据
            if(equityNodePojo!=null){
                nodes.add(equityNodePojo);
            }else{
                nodes.add(new EquityNodePojo());
            }
            temp.setNodes(nodes);
        }
        return ResultBean.ok(list);
    }

    /**
     * 对权益树判断是否重复
     * @param equityTreeVo
     * @return
     */
    public boolean isRepeat(EquityTreeVo equityTreeVo){
         EquityTree temp=new EquityTree();
        temp.setEquityTreeName(equityTreeVo.getEquityTreeName());
        Optional<EquityTree> equityTreeOptional=equityTreeService.findOne(Example.of(temp));
         if(equityTreeOptional.isPresent()){
            EquityTree equityTree=equityTreeOptional.get();
            if(equityTreeVo.getId()!=null && equityTreeVo.getId()!=equityTree.getId()){
                return true;
            }else if(equityTreeVo.getId()==null){
                return true;
            }
        }
        return false;
    }

    /**
     * 节点名允许重复，但是重复的节点对应的产品组必须一致
     * @param equityNodeVo
     * @return
     */
    public Boolean isRepeat(EquityNodeVo equityNodeVo){
        EquityNode temp=new EquityNode();
        temp.setName(equityNodeVo.getName());
        temp.setTreeId(equityNodeVo.getTreeId());
        Optional<EquityNode> equityTreeNodeOptional=equityNodeService.findOne(Example.of(temp));
        if(equityTreeNodeOptional.isPresent()){
            EquityNode equityNode=equityTreeNodeOptional.get();
            if(equityNodeVo.getId()!=null && equityNodeVo.getId()!=equityNode.getId()){
                if(equityNodeVo.getGroupId() != equityNode.getGroupId()){
                    return true;
                }
            }else if(equityNodeVo.getId()==null){
                if(equityNodeVo.getGroupId() != equityNode.getGroupId()){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * <p><b>Title:</b> createRootNode</p>
     * <p><b>Description:</b> 根节点是创建权益树后自动生成</p>
     *
     * @param EquityTree
     *
     */
    public EquityNode createRootNode(EquityTree EquityTree) {
        EquityNode equityNode = new EquityNode();
        equityNode.setName("Root");
        equityNode.setTreeId(EquityTree.getId());
        equityNode.setParentId(0l);
        equityNode.setEquityNodeId(EquityTree.getEquityTreeName() + "@" + equityNode.getName());
        equityNode.setStatus("0");
        equityNode.setHierarchy(1);
        equityNode.setDeleteStatus(0);
        equityNode.setNodeAlias("Root");
        EquityNode.putTimeAndUser(equityNode);
        return equityNodeService.save(equityNode);
    }


    /**
     * 对传入的权益树对象根据权益树名进行分装
     * @param map
     * @param list
     * @return
     */
    public Map<String, EquityTreeVo> getPcEquityTreeMap (Map<String, EquityTreeVo> map, List<EquityTreeAndNodesExcelPojo> list){
        for (EquityTreeAndNodesExcelPojo pcEquityTreeAndNode : list) {
            EquityTreeVo equityTree = new EquityTreeVo();;
            if (!map.containsKey(pcEquityTreeAndNode.getEquityTreeName())) {
                BeanUtils.copyProperties(pcEquityTreeAndNode,equityTree);
            } else {
                equityTree = map.get(pcEquityTreeAndNode.getEquityTreeName());
            }
            map.put(pcEquityTreeAndNode.getEquityTreeName(), equityTree);
        }
        return map;
    }

    public Boolean checkImport(Map<String, EquityTreeVo> map,List<EquityTreeAndNodesExcelPojo> list,StringBuffer errMessage){
        Boolean flag=true;
        for (Map.Entry<String, EquityTreeVo> entry : map.entrySet()){
            EquityTreeVo vo=entry.getValue();
            List<String> messageList = ValidateFilter.getFilterMessage(vo, Constants.VALIDATE_DEFAULT);
            if (flag && !messageList.isEmpty()) {
                errMessage.append("权益树:" + vo.getEquityTreeName() + ":" + messageList.toString() + ";");
                return false;
            }

            if (flag && isRepeat(vo)) {
                errMessage.append("权益树:" + vo.getEquityTreeName() + ":" + MessageCodes.get(MessageCodes.M980014) + ";");
                return false;
            }
        }

        for(EquityTreeAndNodesExcelPojo pojo:list){
            EquityNodeVo equityNodeVo=new EquityNodeVo();
            equityNodeVo.setName(pojo.getName());
            equityNodeVo.setGroupId(pojo.getGroupId());
            equityNodeVo.setNodeAlias(pojo.getNodeAlias());
            equityNodeVo.setStatus("启用".equals(pojo.getStatus())?"0":"1");
            equityNodeVo.setHierarchy(pojo.getHierarchy());
            equityNodeVo.setTreeId(1L);
            equityNodeVo.setEquityNodeId(pojo.getEquityTreeName()+"@"+pojo.getName());
            equityNodeVo.setParentId(1L);
            List<String> messageList = ValidateFilter.getFilterMessage(equityNodeVo, Constants.VALIDATE_DEFAULT);
            if (!messageList.isEmpty()) {
                errMessage.append("子节点:").append(equityNodeVo.getName()).append(":").append(messageList.toString()).append(";");
                return false;
            }
            if (isRepeat(equityNodeVo)) {
                errMessage.append("权益节点:").append(equityNodeVo.getName()).append(":").append("节点名重复时产品组必须一致！ ");
                return false;
            }
            ProductGroup group = productGroupService.findById(pojo.getGroupId());
            if(group == null) {
                errMessage.append("此产品组:").append(equityNodeVo.getGroupId()).append(":").append("不存在;");
                return false;
            }
        }
        return flag;
    }

    /**
     * 保存权益树和节点
     * @param msg
     * @param errMessage
     * @param successNum
     * @param errorNum
     * @param map
     * @param list
     */
    public StringBuffer saveEquityTree(StringBuffer msg,StringBuffer errMessage,AtomicInteger successNum,AtomicInteger errorNum,Map<String, EquityTreeVo> map,List<EquityTreeAndNodesExcelPojo> list){
        for (Map.Entry<String, EquityTreeVo> entry : map.entrySet()){
            EquityTreeVo vo=entry.getValue();
            EquityTree equityTree = new EquityTree();
            BeanUtils.copyProperties(vo,equityTree);
            if("否".equals(vo.getAutoPublish())){
                equityTree.setActiveStatus("2");
            }else if("是".equals(vo.getAutoPublish())){
                //todo  权益树发布
                //equityTree.setActiveStatus("0");
                Boolean flag = sendAbility.sendToAbility(equityTree.getId(),1,equityTree.getEquityTreeName(),"1");
                if(flag){
                    equityTree.setActiveStatus("0");
                }else {
                    equityTree.setActiveStatus("2");
                }
            }
            EquityTree.putTimeAndUser(equityTree);
            equityTree.setEquityTreeDepth(0);
            equityTree=equityTreeService.save(equityTree);
            successNum.addAndGet(1);
            EquityNode root=createRootNode(equityTree);
            equityTree.setEquityTreeDepth(1);
            equityTree=equityTreeService.save(equityTree);
            saveEquityNodes(equityTree,list,errMessage, errorNum,root.getId());
        }
        msg.append(errMessage + ";");
        return msg;
    }

    public void saveEquityNodes(EquityTree equityTree, List<EquityTreeAndNodesExcelPojo> list, StringBuffer errMessage, AtomicInteger errorNum,Long rootId){
        Map<String, Long> map = new HashMap<>();
         int depth = 0;//权益树的深度

        for(EquityTreeAndNodesExcelPojo pojo:list){
            EquityNodeVo equityNodeVo=new EquityNodeVo();
            equityNodeVo.setName(pojo.getName());
            equityNodeVo.setGroupId(pojo.getGroupId());
            equityNodeVo.setNodeAlias(pojo.getNodeAlias());
            equityNodeVo.setStatus("启用".equals(pojo.getStatus())?"0":"1");
            equityNodeVo.setHierarchy(pojo.getHierarchy());
            equityNodeVo.setTreeId(equityTree.getId());
            equityNodeVo.setEquityNodeId(pojo.getEquityTreeName()+"@"+pojo.getName());
            equityNodeVo.setParentId(equityNodeVo.getHierarchy()==2?rootId:map.get(equityTree.getEquityTreeName()+"@"+(equityNodeVo.getHierarchy()-1)));
            /*List<String> messageList = ValidateFilter.getFilterMessage(equityNodeVo, Constants.VALIDATE_DEFAULT);
            if (!messageList.isEmpty()) {
                errMessage.append("子节点:").append(equityNodeVo.getName()).append(":").append(messageList.toString()).append(";");
                errorNum.addAndGet(1);
                //equityTreeService.deleteById(equityTree.getId());
                return;
            }
            if (isRepeat(equityNodeVo)) {
                errMessage.append("权益节点:").append(equityNodeVo.getName()).append(":").append("节点名重复时产品组必须一致！ ");
                errorNum.addAndGet(1);
                //equityTreeService.deleteById(equityTree.getId());
                return;
            }
            ProductGroup group = productGroupService.findById(pojo.getGroupId());
            if(group == null) {
                errMessage.append("此产品组:").append(equityNodeVo.getGroupId()).append(":").append("不存在;");
                errorNum.addAndGet(1);
                //equityTreeService.deleteById(equityTree.getId());
                return;
            }*/
            EquityNode equityNode=new EquityNode();
            BeanUtils.copyProperties(equityNodeVo,equityNode);
            equityNode.setDeleteStatus(0);
            EquityNode.putTimeAndUser(equityNode);
            equityNode=equityNodeService.save(equityNode);
            if(equityNodeVo.getHierarchy()>depth){
                depth=equityNodeVo.getHierarchy().intValue();
            }
            equityTree.setEquityTreeDepth(depth);
            equityTreeService.save(equityTree);
            map.put(equityTree.getEquityTreeName()+"@"+equityNode.getHierarchy() , equityNode.getId());
        }
    }

}
